
(function(){
	var initializing = false,
		fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
	
	this.Class = function(){};
	
	Class._extends = function(prop) {
		var _super = this.prototype;
		
		initializing = true;
		var prototype = new this();
		initializing = false;
		
		for (var name in prop) {
			prototype[name] = typeof prop[name] == "function" && 
				typeof _super[name] == "function" && fnTest.test(prop[name]) ?
				(function(name, fn){
					return function() {
						var tmp = this._super;
						this._super = _super[name];
						var ret = fn.apply(this, arguments);				
						this._super = tmp;
						
						return ret;
					};
				})(name, prop[name]) :
				prop[name];
		}
		
		function Class() {
			if(!initializing && this._constructor)
				this._constructor.apply(this, arguments);
		}
		
		Class.prototype = prototype;
		Class.prototype.constructor = Class;
		Class._extends = arguments.callee;
		
		return Class;
	};
	
	this.pjs = function() {};
	
	pjs.init = function(main, width, height, bgcolor, scaleMode, frameRate) {
		root = document.body;
		stage = new pjs.display.Stage(width, height, bgcolor, scaleMode, frameRate);
		window.onresize = stage.onresize;
		
		root.appendChild(stage.content);
		root.style.padding = root.style.margin = "0";
		root.style.overflow = "hidden";
		
		stage.onresize();
		
		main();
	};
	
	this._package = function() {
		var path = arguments.length > 1 ? arguments[0] : null,
			objs = arguments.length > 1 ? arguments[1] : arguments[0],
			loc = this,
			classRef;
		
		if(path) {
			var pathArr = path.split(".") || [path];
			for(var p in pathArr) {
				if(!loc[pathArr[p]]) loc[pathArr[p]] = {};
				loc = loc[pathArr[p]];
			}
			
			path += ".";
		}
		
				
		for(var o in objs) {
			classRef = objs[o]._extends ? objs[o]._extends : Class;
			if(!classRef) throw new Error("Reference to " + o + " can not be found.");
			
			delete objs[o]._extends;
			loc[o] = classRef._extends(objs[o]);
		}
	};
	
})();

_package('pjs.geom', {
	Point : {
		_constructor : function(x, y) {
			this.x = x | 0;
			this.y = y | 0;
		},
		
		toString : function() {
			return "Point("+this.x+", "+this.y+")";
		}
	},
	
	Rectangle : {
		_constructor : function(x, y, width, height) {
			this.x = x | 0;
			this.y = y | 0;
			this.width = width | 0;
			this.height = height | 0;
		},
		
		contains : function(rect) {
			if(rect.x < this.x
			|| rect.x + rect.width > this.x + this.width
			|| rect.y < this.y
			|| rect.y + rect.height > this.y + this.height) return false;
			
			return true;
		},
		
		intersects : function(rect) {
			if(rect.x >= this.x + this.width
			|| rect.x + rect.width <= this.x
			|| rect.y >= this.y + this.height
			|| rect.y + rect.height <= this.y) return false;
			
			return true;
		},
		
		merge : function(rect) {
			var r = new pjs.geom.Rectangle();
			r.x = this.x < rect.x ? this.x : rect.x;
			r.y = this.y < rect.y ? this.y : rect.y;
			r.width = (this.x + this.width > rect.x + rect.width ? this.x + this.width : rect.x + rect.width) - r.x;
			r.height = (this.y + this.height > rect.y + rect.height ? this.y + this.height : rect.y + rect.height) - r.y;
			return r;
		},
		
		toString : function() {
			return "Rectangle("+this.x+", "+this.y+", "+this.width+", "+this.height+")";
		}
	}
});

_package("pjs.events", {
	EventDispatcher : {
		_constructor : function() {
			this.events = {};
		},
		
		addEventListener : function(e, trigger, params) {
            this.removeEventListener(e, trigger);

            this.events[e].push({trigger:trigger, params:params});
		},
		
		removeEventListener : function(e, trigger) {
			if(this.events[e] == undefined) {
				this.events[e] = [];
				return;
			}
			
			for(var s=this.events[e].length-1; s>=0; s--) {
				if(this.events[e][s].trigger != trigger)
					continue;
				
				this.events[e].splice(s, 1);
			}
		},
		
		dispatchEvent : function(e) {
			if(this.events[e] == undefined)
				return;
			
			for(var i=this.events[e].length-1; i>=0; i--) {
				this.events[e][i].trigger(this.events[e][i].params);
			}
		}
	}
});

_package("pjs.display", {
	Graphic : {
		_constructor : function(src, width, height) {
			//var i = pjs.images.indexOf();
			this.width = width | 0;
			this.height = height | 0;
			this.data = new Image();
			this.data.onload = this.onload;
			this.data.name = src.indexOf('/') == -1 ? src.substring(0, src.lastIndexOf('.')) : src.substring(src.lastIndexOf('/') + 1, src.lastIndexOf('.'));
			this.data.src = src;
		},
		
		onload : function() {
			//alert(document.images);
		}
	}
});

_package("pjs.display", {
	DisplayObjectContainer : { _extends : pjs.events.EventDispatcher,
		
		_constructor : function() {
			this.x = 0;
			this.y = 0;
			this.children = 0;
			this.container = document.createElement("div");
			this.style = this.container.style;
		},
		
		addChild : function(child) {
			this.removeChild(child);
			this.container.appendChild(child.container);
			this.children.push(child);
		},
		
		removeChild : function(child) {
			var i = this.children.indexOf(child);
			
			if(i == -1) return;
			
			this.children.splice(i, 1);
		}
	}
});

_package("pjs.display", {
	Stage : { _extends : pjs.display.DisplayObjectContainer,
		_constructor : function(width, height, bgcolor, scaleMode, frameRate) {
			var canvas = document.createElement("canvas"),
				graphics = canvas.getContext("2d");
			
			
			
			canvas.width = width;
			canvas.height = height;
			
			graphics.fillStyle = bgcolor;
			graphics.fill();
			
			this.content = document.createElement("div");
			
			this.style = this.content.style;
			this.style.background = bgcolor;
			this.style.position = "absolute";
			this.style.overflow = "hidden";
			this.style.width = width + "px";
			this.style.height = height + "px";
			
			this.frameRate = frameRate || 60;
			this.align = "";
			this.scaleMode = scaleMode || "noresize";
			this.scaleX = this.scaleY = 1;
			this.width = this.scaledWidth = width;
			this.height = this.scaledHeight = height;
			
		},
		
		onresize : function() {
			pjs.resize = false;
			
			window.width = window.innerWidth || document.body.clientWidth,
			window.height = window.innerHeight || document.body.clientHeight;
			
			if(stage.scaleMode != "noresize") {
				stage.scaleX = window.width / stage.width;
				stage.scaleY = window.height / stage.height;
				
				if(stage.scaleMode == "keepAspect") {
					if(stage.scaleX * stage.height > window.height)
						stage.scaleX = stage.scaleY;
					else
						stage.scaleY = stage.scaleX;
				}
				
				stage.scaledWidth = stage.width * stage.scaleX;
				stage.scaledHeight = stage.height * stage.scaleY;
				
				stage.style.width = stage.scaledWidth + "px";
				stage.style.height = stage.scaledHeight + "px";
			}
			
			if(stage.align.indexOf("l") >= 0)
				stage.style.left = "0";
			else if(stage.align.indexOf("r") >= 0)
				stage.style.left = (window.width - stage.scaledWidth) + "px";
			else
				stage.style.left = ((window.width - stage.scaledWidth) >> 1) + "px";
			
			if(stage.align.indexOf("t") >= 0)
				stage.style.top = "0";
			else if(stage.align.indexOf("b") >= 0)
				stage.style.top = (window.height - stage.scaledHeight) + "px";
			else
				stage.style.top = ((window.height - stage.scaledHeight) >> 1) + "px";
			
			/*if(stage.scaleMode != "noresize") pjs.resizeBitmaps();*/
		}
	}
});



_package("pjs.display", {
	SpriteSheet : {
		_constructor : function(img, rect, frameWidth, frameHeight, flip, rotations) {
			var canvas = document.createElement('canvas'),
				context = canvas.getContext('2d');
			
			if(!rect) rect = new pjs.geom.Rectangle(0, 0, img.width, img.height);
			
			canvas.width = flip ? this.rect.width << 1 : this.rect.width;
			canvas.height = this.rect.height;
			
			//context.drawImage(img, 0, 0);
			
			context.drawImage(
				img,
				rect.x,
				rect.y,
				rect.width,
				rect.height,
				0,
				0,
				rect.width,
				rect.height);
			
			if(flip) {
				context.translate(canvas.width, 0);
				context.scale(-1, 1);
				//context.drawImage(img, 0, 0);
				context.drawImage(
					img,
					rect.x,
					rect.y,
					rect.width,
					rect.height,
					0,
					0,
					rect.width,
					rect.height);
			}
			
			this.image = canvas;
			//this.imageData = context;
			this.imageData = context.getImageData(0, 0, canvas.width, canvas.height);
			
			this.flipped = flip ? true : false;
			this.frames = {};
			this.frameWidth = frameWidth;
			this.frameHeight = frameHeight;
			this.cols = (this.rect.width / frameWidth) << 0;
			this.rows = (this.rect.height / frameHeight) << 0;
			this.sequences = {};
			this.rotations = rotations | 0;
			this.rotateAngle = this.rotations / 180;
			
			// build frames
			for(var r = 0; r < this.rows; r++) for(var c = 0; c < this.cols; c++) {
				this.frames[c + r * this.cols] = {
					x : c * frameWidth,
					y : r * frameHeight,
					col : c,
					row : r,
					width : frameWidth,
					height : frameHeight,
					offsetX : frameWidth >> 1,
					offsetY : frameHeight >> 1
				};
			}
		},
		
		addSequence : function(label, col, row, colspan, rowspan) {
			colspan = colspan ? colspan : 1;
			rowspan = rowspan ? rowspan : 1;
			
			var sequence = { length : colspan * rowspan };
			
			for(var r = row, c; r < row + rowspan; r++) for (c = col; c < col + colspan; c++) {
				sequence[sequence.length] = this.frames[c + r * this.cols];
				sequence.length++;
			}
			
			this.sequences[label] = sequence;
		}
	}
});



window.onload = function() {
	
	var obj = document.images,
		str = "";
	for(var i in obj) str += i + " = " + obj[i] + "\n";
	alert(str);
	
	
};
